﻿using System;
using System.Collections.Generic;
using Com.AAS.Toolbox.DataMirror.Config;
using Com.AAS.Toolbox.DataMirror.Server.Event;
using Com.AAS.Toolbox.DataMirror.Server.Handler;
using Com.AAS.Toolbox.DataMirror.Server.Handler.Impl;
using Com.AAS.Common.Queue;
using Com.AAS.Common.Utils;

namespace Com.AAS.Toolbox.DataMirror.Server
{
    class FileSystemCoreServer : QueueHandler<MonitorEvent>, EventListener
    {
        List<FileSystemScanHandler> scanHandlers = new List<FileSystemScanHandler>();
        List<FileSystemMonitorHandler> monitorHandlers = new List<FileSystemMonitorHandler>();
        List<FileSystemFilterHandler> filterHandlers = new List<FileSystemFilterHandler>();
        List<FileSystemImageHandler> imageHandelers = new List<FileSystemImageHandler>();
        List<FileSystemLogHandler> logHandelers = new List<FileSystemLogHandler>();

        public FileSystemScanHandler[] FileSystemScanHandlers
        {
            get
            {
                return scanHandlers.ToArray();
            } 
            set
            {
                scanHandlers.Clear();
                scanHandlers.AddRange(value);
            }
        }

        public FileSystemMonitorHandler[] FileSystemMonitorHandlers
        {
            get
            {
                return monitorHandlers.ToArray();
            }
            set
            {
                monitorHandlers.Clear();
                monitorHandlers.AddRange(value);
            }
        }

        public FileSystemFilterHandler[] FileSystemFilterHandlers
        {
            get
            {
                return filterHandlers.ToArray();
            }
            set
            {
                filterHandlers.Clear();
                filterHandlers.AddRange(value);
            }
        }

        public FileSystemCoreServer(FileSystemConfig config)
        {

            newLogEvent(LogLevel.I, "config loading", config.ApplicationName + "(" + config.Version + ")");
            
            if (config.FilerTags.Length > 0)
            {
                // 初始化过滤器 
                FileSystemFilterHandler hander = new FileSystemFilterHandlerImpl();
                hander.Register(this);
                hander.SetFileFilterEndFixed(config.FilerTags, config.FilterReversal);
                filterHandlers.Add(hander);
                newLogEvent(LogLevel.I, "config loading", "config filter value : " + String.Join(",", config.FilerTags));
            }
            else
                newLogEvent(LogLevel.I, "config loading", "not config filter.");

            // 设置镜像监控器
            foreach (MonitorItem item in config.MonitorItems)
            {
                newLogEvent(LogLevel.I, "config loading", "monitor dir : " + item.Orignal + " -> " + String.Join(",", item.Images));
                if (!String.IsNullOrEmpty(item.Orignal) && item.Images.Length > 0)
                {
                    FileSystemImageHandler hander = new FileSystemImageHandlerImpl()
                    {
                        MonitorPath = item.Orignal,
                        ImagePaths = item.Images
                    };
                    {
                        hander.Register(this);
                        imageHandelers.Add(hander);
                    }
                }
            }
            if(config.MonitorItems.Length == 0)
                newLogEvent(LogLevel.I, "config loading", "not config monitor dir.");
                
            // 
            {
                FileSystemLogHandler hander = new FileSystemLogHandlerImpl();
                hander.Register(this);
                logHandelers.Add(hander);
            }

            this.ToStart();

            // 设置监控目录--文件初始化扫描
            foreach (MonitorItem item in config.MonitorItems)
            {
                if (!String.IsNullOrEmpty(item.Orignal))
                {
                    // 文件扫描
                    FileSystemScanHandler hander = new FileSystemScanHandlerImpl()
                    {
                        MonitorPath = item.Orignal,
                        ImagePaths = item.Images
                    };
                    hander.Register(this);
                    scanHandlers.Add(hander);

                    if (item.AuotoSync)
                    {
                        newLogEvent(LogLevel.I, "config loading", "config monitor dir: " + item .Orignal + " to sync .");
                        hander.DoSync();
                    }
                }
            }

            // 设置监控目录--文目录监控
            foreach (MonitorItem item in config.MonitorItems)
            {
                if (!String.IsNullOrEmpty(item.Orignal))
                {
                    // 文件扫描
                    FileSystemMonitorHandler hander = new FileSystemMonitorHandlerImpl();
                    hander.Register(this);
                    hander.DoMonitor(item.Orignal);
                    monitorHandlers.Add(hander);

                    newLogEvent(LogLevel.I, "config loading", "config monitor dir: " + item.Orignal + " to monitor .");
                }
            }

        }

        private void newLogEvent(LogLevel level, String title, String message)
        {
            OnNotice(new MonitorEvent(new LogData(level, title, message)));
        }

        #region EventListener 成员

        public void OnNotice(MonitorEvent e)
        {
            // 过滤器进行事件过来
            bool result = true;
            foreach (FileSystemFilterHandler handler in filterHandlers)
            {
                result &= !handler.DoFilter(e);
                if (!result)
                {
                    return;
                }
            }

            // 放入处理器
            Put(e);
        }

        #endregion                                    

        protected override void OnProcess(MonitorEvent item)
        {
            if (item.HasEntityData)
            {
                foreach (FileSystemImageHandler handler in imageHandelers)
                {
                    if (!item.EntityData.OriginalMonitorPath.Equals(handler.MonitorPath))
                        continue;
                    // 数据镜像处理
                    handler.OnProcess(item);
                }
            }
            
            if (item.HasLogData)
            {
                foreach (FileSystemLogHandler handler in logHandelers)
                    handler.AuditLog(item);
            }
        }
        
        internal void Sync()
        {
            // 设置监控目录--文件初始化扫描
            foreach (FileSystemScanHandler handler in scanHandlers)
            {
                // 文件扫同步
                handler.DoSync();
            }
        }
    }
}